﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Input;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using static RhythmGame.Settings;

namespace RhythmGame
{
    public partial class NoteTap : System.Windows.Forms.UserControl
    {
        private int appearTime = 0;
        private int judgeTime = 0;
        private int track = 1;

        public NoteTap()
        {
            InitializeComponent();
        }

        public int AppearTime
        {
            get { return appearTime; }
            set { appearTime = value; }
        }

        public int JudgeTime
        {
            get { return judgeTime; }
            set { judgeTime = value; }
        }

        public int Track
        {
            get { return track; }
            set { track = value; }
        }

        internal static void NextTaps(Game game, BeatMap map, List<NoteTap> currentTaps, Element_info[] blockElements)
        {
            //// 调整 lastTime 和 currentTime，提前 DuringTime
            //int adjustedLastTime = lastTime + Settings.DuringTime;
            //int adjustedCurrentTime = currentTime + Settings.DuringTime;

            //Element_info[] blockElements = map.GetNextTickInfo(adjustedLastTime, adjustedCurrentTime);

            foreach (Element_info _element in blockElements)
            {
                if (_element.TypeId == 1)
                {
                    ElementTap_info element = _element as ElementTap_info;

                    NoteTap tapNote = new NoteTap();

                    // 设置出现时间
                    tapNote.AppearTime = element.ClickTime - Settings.Instance.DuringTime;

                    tapNote.JudgeTime = element.ClickTime;

                    // 设置轨道
                    tapNote.Track = element.X - 1;

                    tapNote.Location = new Point(0, 0);

                    tapNote.Width = element.Width * 40;
                    tapNote.Height = tapNote.Width / 4;
                    tapNote.BackColor = Settings.Instance.BlocksColor;
                    // 根据 x 值设置水平位置
                    int maxTrackWidth = (int)(Settings.Instance.WinWidth * 0.9) / Settings.Instance.MaxKeysQuantity;
                    tapNote.Left = (int)(Settings.Instance.WinWidth * 0.05 + (maxTrackWidth - tapNote.Width) / 2 + maxTrackWidth * (element.X - 1));

                    

                    // 初始垂直位置在窗口顶部
                    tapNote.Top = 0;

                    game.Controls.Add(tapNote);

                    currentTaps.Add(tapNote);
                    tapNote.BringToFront();

                }
                else
                {
                    continue;
                }
            }
        }
        
        internal static void TapsMove(Game game, List<NoteTap> currentTaps, int currentTime)
        {
            foreach (var tap in currentTaps.ToList())
            {
                // 移除准备清除的音符
                if (game.tapsToRemove.Contains(tap))
                {
                    game.Controls.Remove(tap);
                    //game.SetLabelComboText("Remove Successful");
                    game.tapsToRemove.Remove(tap);
                    currentTaps.Remove(tap);
                    tap.Dispose();
                    continue;
                }

                if (currentTime >= tap.AppearTime)
                {
                    //MessageBox.Show(tap.AppearTime.ToString());
                    int elapsedTime = currentTime - tap.AppearTime;
                    int distance = Settings.Instance.DropSpeed * elapsedTime / Settings.Instance.UnitConversion;
                    //MessageBox.Show(distance.ToString());
                    tap.Top = distance;
                }

                if (tap.Top > Settings.Instance.WinHeight) // 当音符超过窗口高度
                {
                    // 判定为 Miss
                    //game.SetLabelDecideText("MISS");
                    Scoring.ApplyJudgement(game, "MISS", false);

                    // 将音符添加到待移除列表
                    game.tapsToRemove.Add(tap);
                }

            }
        }
        
        // 判定
        internal static void Judgement(Game game, List<NoteTap> currentTaps, int currentTime, List<Tuple<Keys, int>> keysPress)
        {            
            foreach (NoteTap tap in currentTaps.ToList())
            {
                // 跳过已在待移除列表中的音符
                if (game.tapsToRemove.Contains(tap))
                {
                    continue;
                }

                if (Math.Abs(currentTime - tap.JudgeTime) <= 110) // 只在判定时间前后110ms内进行判定
                {
                    foreach (Tuple<Keys, int> key in keysPress.ToList())
                    {
                        if (key.Item1 == Settings.Instance.KeysLocate[tap.Track])
                        {
                            if (Math.Abs(key.Item2 - tap.JudgeTime) <= (int)Settings.JudgeStandard.CriticalPerfect)
                            {
                                // Critical Perfect
                                game.tapsToRemove.Add(tap);
                                //game.SetLabelDecideText("CRITICAL PERFECT");
                                Scoring.ApplyJudgement(game, "CRITICAL PERFECT", false);
                            }
                            else if (Math.Abs(key.Item2 - tap.JudgeTime) <= (int)Settings.JudgeStandard.Perfect)
                            {
                                // Perfect
                                game.tapsToRemove.Add(tap);
                                //game.SetLabelDecideText("PERFECT");
                                Scoring.ApplyJudgement(game, "PERFECT", false);
                            }
                            else if (Math.Abs(key.Item2 - tap.JudgeTime) <= (int)Settings.JudgeStandard.Great)
                            {
                                // Great
                                game.tapsToRemove.Add(tap);
                                //game.SetLabelDecideText("GREAT");
                                Scoring.ApplyJudgement(game, "GREAT", false);
                            }
                            else if (Math.Abs(key.Item2 - tap.JudgeTime) <= (int)Settings.JudgeStandard.Good)
                            {
                                // Good
                                game.tapsToRemove.Add(tap);
                                //game.SetLabelDecideText("GOOD");
                                Scoring.ApplyJudgement(game, "GOOD", false);
                            }
                            else
                            {
                                // Miss
                                //game.SetLabelDecideText("MISS");
                                Scoring.ApplyJudgement(game, "MISS", false);
                            }
                            // 处理完按键后，从 keysPress 中移除对应的按键记录
                            game.keysPress.Remove(key);
                            break; // 处理完匹配的按键后跳出此层循环
                        }
                    }
                }
            }
        }

        public void RemoveFromGame(Game game)
        {
            game.Controls.Remove(this);
        }
    }
}
